﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Ini_Config.Common
{
    internal class Fun
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        //需要调用GetPrivateProfileString的重载
        [DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
        private static extern long GetPrivateProfileString(string section, string key, string? def, StringBuilder retVal, int size, string filePath);

        [DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
        private static extern uint GetPrivateProfileStringA(string section, string key, string def, Byte[] retVal, int size, string filePath);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);


        //单个读取ini文件
        public static string ReadSingleFile(string Section, string Key, string iniFilePath)
        {
            StringBuilder temp = new StringBuilder(1024);
            string result = "";
            if (File.Exists(iniFilePath))
            {
                GetPrivateProfileString(Section, Key, null, temp, 1024, iniFilePath);
                result = temp.ToString();
            }
            return result;
        }
        //单个写入ini文件
        public static bool WriteSingleFile(string Section, string Key, string val, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                WritePrivateProfileString(Section, Key, val, iniFilePath);
                return true;
            }
            return false;
        }
        /// <summary>

        /// 获取INI文件中指定节点(Section)中的所有条目(key=value形式)

        /// </summary>

        /// <param name="iniFile">Ini文件</param>

        /// <param name="section">节点名称</param>

        /// <returns>指定节点中的所有项目,没有内容返回string[0]</returns>

        public static string[] INIGetAllItems(string iniFile, string section)
        {
            //返回值形式为 key=value,例如 Color=Red
            uint MAX_BUFFER = 32767;    //默认为32767
            string[] items = new string[0];      //返回值
            //分配内存
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
            uint bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, iniFile);
            if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
            {
                string? returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
                items = returnedString!.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
            }
            Marshal.FreeCoTaskMem(pReturnedString);     //释放内存
            return items;
        }

        public static string[] GetIniFileNodeNames(string filePath)
        {
            uint MaxBuffer = 32767;
            string[] sections = new string[0];  // 返回值
            // 申请内存
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MaxBuffer * sizeof(char));
            uint byteReturned = GetPrivateProfileSectionNames(pReturnedString, MaxBuffer, filePath);
            if (byteReturned != 0)
            {
                // 读取指定内存内容
                string local = Marshal.PtrToStringAuto(pReturnedString, (int)byteReturned)!.ToString();
                // 每个节点之间用\0分隔,末尾有一个\0 
                sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
            }

            return sections;
           
        }
    }
}
